﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace Zadanie1
{
    class ProducerConsumerProblem
    {
        private const int N = 20;
        private bool[] state;
        private int consumerIndex = 0;
        private int producerIndex = 0;

        Semaphore products, places;

        Random random;

        private StatePreviewForm statePreviewForm = new StatePreviewForm();

        private void consumer()
        {
            while (statePreviewForm.Visible)
            {
                products.WaitOne();
                updateState();
                state[consumerIndex] = false;
                consumerIndex = (consumerIndex + 1) % N;
                Thread.Sleep((random.Next() % 10) * 150 + 100);
                places.Release();
            }
        }

        private void producer()
        {
            while (statePreviewForm.Visible)
            {
                places.WaitOne();
                updateState();
                state[producerIndex] = true;
                producerIndex = (producerIndex + 1) % N;
                Thread.Sleep((random.Next()%10)*100+100);
                products.Release();
            }
        }

        private void updateState()
        {
            String description = "";
            foreach (bool b in state)
            {
                description += b ? "T " : "F ";
            }

            statePreviewForm.StateDescription = description;
        }

        public StatePreviewForm Run()
        {
            state = new bool[N];
            random = new Random();

            statePreviewForm.Visible = true;

            products = new Semaphore(0, N);
            places = new Semaphore(N, N);
            Thread consumerThread = new Thread(new ThreadStart(consumer));
            Thread producerThread = new Thread(new ThreadStart(producer));

            consumerThread.Start();
            producerThread.Start();

            return statePreviewForm;
        }
    }
}
